#include "../import/head.h"
#include "proc_misc.h"
#include "../data_struct/head.h"
#include "../global/head.h"
#include "../macro/head.h"
#include "../msg/head.h"
#include "../helper_package/head.h"
#include "../helper_heart/head.h"
#include "../helper_net/head.h"
#include "../helper_tcp/head.h"
#include "../helper_udp/head.h"
#include "../wnd_login/head.h"
#include "../wnd_main/head.h"

namespace xos_sgsj
{

    proc_misc::proc_misc()
    {
    }

    proc_misc::~proc_misc()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int proc_misc::proc( data * pData )
    {
        int ret = 0;

        int nMsg = pData->m_nMsg;

        switch( nMsg )
        {
            // program msg
            case MSG_START_PROGRAM:
                {
                    ret = start_tcp();
                }
                break;
            case MSG_TCP_STARTED:
                {
                    ret = on_start_tcp( pData );
                }
                break;
			case MSG_SSL:
				{
					ret = on_start_ssl( pData );
				}
				break;
            case MSG_UDP_STARTED:
                {
                    ret = on_start_udp( pData );
                }
                break;
            case MSG_PROGRAM_STARTED:
                {
                    ret = on_program_started();
                }
                break;
            case MSG_QUITING:
                {
					g_pSysData->m_bIsRunning = false;
                    g_pSysData->m_bQuiting = true;
                    ret = stop_net();
                }
                break;
            case MSG_NET_STOPPED:
                {
                    ret = post_quitted();
                }
                break;
            case MSG_QUITED:
                {
					on_program_quitted();
                }
                break;
            default:
                {
                    ret = 1;
                }
                break;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int proc_misc::on_start_tcp( data * pData )
    {
        int ret = 0;

        if( pData->m_bSuccess )
        {
            ret = start_ssl( pData->m_pTcp );
        }
        else
        {
            LOG4( "start tcp server failed" );
            ret = post_quitting();
        }

        return ret;
    }

    int proc_misc::start_tcp()
    {
        int ret = 0;

        session * pSession = 0;
        tcp * pTcp = 0;

        if( 0 == ret )
        {
            pSession = g_pSysData->m_pPool->m_session_pool.GetItem();
            pSession->init();
            pSession->m_eType = session::TYPE_TCP_DATA;
        }

        if( 0 == ret )
        {
            pTcp = g_pSysData->m_pPool->m_tcp_pool.GetItem();
            pTcp->init();
        }

        if( 0 == ret )
        {
            pTcp->m_pSession = pSession;
            pSession->m_pTcp = pTcp;
            g_pSysData->m_os.m_pCrt->strcpy( pTcp->m_szIp, g_pSysData->m_config.tcp_server_ip );
            pTcp->m_nPort = g_pSysData->m_config.tcp_server_port;
            net_tcp obj;
            ret = obj.tcp_post_connect( pTcp );
            pSession = 0;
            pTcp = 0;
        }

        if( pSession )
        {
            pSession->release();
            pSession = 0;
        }

        if( pTcp )
        {
            pTcp->release();
            pTcp = 0;
        }

        return ret;
    }

	int proc_misc::on_start_ssl( data * pData )
	{
		int ret = 0;

		if( pData->m_bSuccess )
		{
			ret = start_udp();
		}
		else
		{
			LOG4( "start ssl connect failed" );
			ret = post_quitting();
		}

		return ret;
	}

	int proc_misc::start_ssl( tcp * pTcp )
	{
		int ret = 0;

		protocol_ssl obj;
		ret = obj.compose( pTcp );

		return ret;
	}

    int proc_misc::on_start_udp( data * pData )
    {
        int ret = 0;

        if( pData->m_bSuccess )
        {
            data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
            p->init();
            p->m_nMsg = MSG_PROGRAM_STARTED;
            g_pSysData->notify( p );
        }
        else
        {
            LOG4( "start udp server failed" );
            ret = post_quitting();
        }

        return ret;
    }

    int proc_misc::start_udp()
    {
        int ret = 0;

        data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
        p->init();
        p->m_nMsg = MSG_UDP_STARTED;
        p->m_bSuccess = true;
        g_pSysData->notify( p );

        return ret;
    }

    int proc_misc::on_program_started()
    {
        int ret = 0;

        g_pSysData->m_bIsRunning = true;
		LOG4( "program start success" );
    
        return ret;
    }

    int proc_misc::on_program_quitted()
    {
        int ret = 0;

		QWidget * pWnd = g_pSysData->m_pLoginDlg;
		if( !pWnd )
		{
			pWnd = g_pSysData->m_pImpl;
		}

		if( !g_pSysData->m_bUserQuit )
		{
			QMessageBox::information( pWnd, QObject::tr( "network error" ), QObject::tr( "failed to connect to server" ) );
		}

		g_pSysData->m_bQuit = true;
		pWnd->close();

		LOG3( "quit" );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int proc_misc::stop_net()
    {
        int ret = 0;

        session::LIST & s_list = g_pSysData->m_pPool->m_session_list;
        int nCloseNum = 0;

        for( session * p = s_list.begin(); ( 0 == ret ) && ( p != s_list.end() ); p = p->m_pNext )
        {
            p->sub_ref( 1 );
            nCloseNum++;
        }

        if( 0 == nCloseNum )
        {
            data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
            p->init();
            p->m_nMsg = MSG_NET_STOPPED;
            g_pSysData->notify( p );
        }

        return ret;
    }

    int proc_misc::post_quitting()
    {
        int ret = 0;

        data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
        p->init();
        p->m_nMsg = MSG_QUITING;
        g_pSysData->notify( p );

        return ret;
    }

    int proc_misc::post_quitted()
    {
        int ret = 0;

        data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
        p->init();
        p->m_nMsg = MSG_QUITED;
        g_pSysData->notify( p );

        return ret;
    }

} // xos_sgsj
